#pragma once
#include "framework.h"
#include "ServerTask.h"

typedef struct {
	long long send_flow;
	long long recv_flow;
	long send_count;
	long recv_count;
	long error;
	long success;
	long sorted;
	std::vector<int>* vecData;
}PorxyInfoApi;

extern int shooklogid;
extern std::map<std::string, PorxyInfoApi*> ProxyApi;

class ServerHookProtocol :
	public BaseWorker
{
public:
	ServerHookProtocol() {};
	virtual ~ServerHookProtocol() {};
	virtual void ConnectionMade(HSOCKET hsock, PROTOCOL protocol) = 0;
	virtual void ConnectionFailed(HSOCKET hsock, int err) = 0;
	virtual void ConnectionClosed(HSOCKET hsock, int err) = 0;
	virtual void ConnectionRecved(HSOCKET hsock, const char* data, int len) = 0;

	virtual void init() = 0;
	virtual void reinit() = 0;
	virtual void http_handler(HSOCKET hsock, const char* data, int len) = 0;
	virtual void event_handler(cJSON* root) = 0;
	virtual void event_task(ServerTaskConfig* taskcfg, const char* event) = 0;
	virtual void event_agent(t_sheeps_agent* agent, const char* event) = 0;

	virtual void proxy_connect_open_hook(const char* proxy_type, const char* host, HSOCKET from, HSOCKET to, PROTOCOL protocol) = 0;
	virtual void proxy_connect_faile_hook(const char* proxy_type, const char* host, HSOCKET from, HSOCKET to, PROTOCOL protocol) = 0;
	virtual void proxy_connect_close_hook(const char* proxy_type, HSOCKET from, HSOCKET to, PROTOCOL protocol) = 0;
	virtual int proxy_connect_send_hook(const char* proxy_type, HSOCKET from, HSOCKET to, PROTOCOL protocol, const char* data, int len) = 0;
	virtual int proxy_connect_recv_hook(const char* proxy_type, HSOCKET from, HSOCKET to, PROTOCOL protocol, const char* data, int len) = 0;
	static void proxy_api_flow_send(const char* api, int flow, int count){
		PorxyInfoApi* info;
    	std::map<std::string, PorxyInfoApi*>::iterator iter = ProxyApi.find(api);
    	if (iter != ProxyApi.end()){
        	info = iter->second;
        	info->send_flow += flow;
        	info->send_count += count;
    	}
    	else{
        	info = (PorxyInfoApi*)malloc(sizeof(PorxyInfoApi));
        	if (info){
            	memset(info, 0x0, sizeof(PorxyInfoApi));
				info->vecData = new std::vector<int>;

            	info->send_flow += flow;
            	info->send_count += count;
        	}
    	}
	}
	static void proxy_api_flow_recv(const char* api, int flow, int count){
		PorxyInfoApi* info;
    	std::map<std::string, PorxyInfoApi*>::iterator iter = ProxyApi.find(api);
    	if (iter != ProxyApi.end()){
        	info = iter->second;
        	info->recv_flow += flow;
        	info->recv_count += count;
    	}
    	else{
        	info = (PorxyInfoApi*)malloc(sizeof(PorxyInfoApi));
        	if (info){
            	memset(info, 0x0, sizeof(PorxyInfoApi));
				info->vecData = new std::vector<int>;

            	info->recv_flow += flow;
            	info->recv_count += count;
        	}
    	}
	}
	static void proxy_api_response_time(const char* api, int response_time){
		PorxyInfoApi* info;
    	std::map<std::string, PorxyInfoApi*>::iterator iter = ProxyApi.find(api);
    	if (iter != ProxyApi.end()){
        	info = iter->second;
        	if (response_time >= 0){
            	info->success += 1;
            	info->vecData->push_back(response_time);
        	}
        	else{
            	info->error -= response_time;
        	}
    	}
    	else{
        	info = (PorxyInfoApi*)malloc(sizeof(PorxyInfoApi));
        	if (info){
            	memset(info, 0x0, sizeof(PorxyInfoApi));
				info->vecData = new std::vector<int>;
				
            	if (response_time >= 0){
                	info->success += 1;
                	info->vecData->push_back(response_time);
            	}
            	else{
                	info->error -= response_time;
            	}
        	}
    	}
	}
};

typedef ServerHookProtocol* (*ServerCallbackCreate)();
extern ServerCallbackCreate server_hook_create_func;
extern ServerHookProtocol* server_hook;

void server_hook_create();
void server_hook_init();
void server_hook_reinit();